home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / glibc108.gz / glibc108 / glibc-1.08.1 / sysdeps / mach / hurd / i386 / trampoline.c < prev   
Encoding:
C/C++ Source or Header  |  1994-05-01  |  2.9 KB  |  102 lines

  1. /* Set thread_state for sighandler, and sigcontext to recover.  i386 version.
  2. Copyright (C) 1994 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4.  
  5. The GNU C Library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Library General Public License as
  7. published by the Free Software Foundation; either version 2 of the
  8. License, or (at your option) any later version.
  9.  
  10. The GNU C Library is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13. Library General Public License for more details.
  14.  
  15. You should have received a copy of the GNU Library General Public
  16. License along with the GNU C Library; see the file COPYING.LIB.  If
  17. not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  18. Cambridge, MA 02139, USA.  */
  19.  
  20. #include <hurd/signal.h>
  21. #include <mach/thread_status.h>
  22.  
  23. static void
  24. trampoline (void (*handler) (int signo, int sigcode, struct sigcontext *scp),
  25.         int signo, int sigcode, struct sigcontext *scp)
  26. {
  27.   (*handler) (signo, sigcode, scp);
  28.   (void) __sigreturn (scp);    /* Does not return.  */
  29.   while (1)
  30.     asm volatile ("hlt");        /* Firewall.  */
  31. }
  32.  
  33. struct sigcontext *
  34. _hurd_setup_sighandler (int flags,
  35.             __sighandler_t handler,
  36.             struct sigaltstack *sigaltstack,
  37.             int signo, int sigcode,
  38.             void *state)
  39. {
  40.   struct i386_thread_state *ts;
  41.   void *sigsp;
  42.   struct sigcontext *scp;
  43.   struct 
  44.     {
  45.       void *retaddr;        /* Never used.  */
  46.       __sighandler_t handler;
  47.       int signo;
  48.       int sigcode;
  49.       struct sigcontext *scp;    /* Points to ctx, below.  */
  50.       struct sigcontext ctx;
  51.     } *stackframe;
  52.  
  53.   ts = state;
  54.  
  55.   if ((flags & SA_ONSTACK) &&
  56.       !(sigaltstack->ss_flags & (SA_DISABLE|SA_ONSTACK)))
  57.     {
  58.       sigsp = sigaltstack->ss_sp + sigaltstack->ss_size;
  59.       sigaltstack->ss_flags |= SA_ONSTACK;
  60.       /* XXX need to set up base of new stack for
  61.      per-thread variables, cthreads.  */
  62.     }
  63.   else
  64.     sigsp = (char *) ts->uesp;
  65.  
  66.   /* Push the arguments to call `trampoline' on the stack.  */
  67.   sigsp -= sizeof (*stackframe);
  68.   stackframe = sigsp;
  69.   stackframe->handler = handler;
  70.   stackframe->signo = signo;
  71.   stackframe->sigcode = sigcode;
  72.   stackframe->scp = scp = &stackframe->ctx;
  73.  
  74.   /* Set up the sigcontext from the current state of the thread.  */
  75.  
  76.   scp->sc_onstack = sigaltstack->ss_flags & SA_ONSTACK ? 1 : 0;
  77.  
  78.   scp->sc_gs = ts->gs;
  79.   scp->sc_fs = ts->fs;
  80.   scp->sc_es = ts->es;
  81.   scp->sc_ds = ts->ds;
  82.  
  83.   scp->sc_edi = ts->edi;
  84.   scp->sc_esi = ts->esi;
  85.   scp->sc_ebp = ts->ebp;
  86.  
  87.   scp->sc_ebx = ts->ebx;
  88.   scp->sc_edx = ts->edx;
  89.   scp->sc_ecx = ts->ecx;
  90.   scp->sc_eax = ts->eax;
  91.   
  92.   scp->sc_eip = ts->eip;
  93.   scp->sc_uesp = ts->uesp;
  94.   scp->sc_efl = ts->efl;
  95.  
  96.   /* Modify the thread state to call `trampoline' on the new stack.  */
  97.   ts->uesp = (int) sigsp;
  98.   ts->eip = (int) &trampoline;
  99.  
  100.   return scp;
  101. }
  102.